#include <gtest/gtest.h>
#include <thread>
#include "scheduler/sequence_scheduler.h"
#include "scheduler/fallback_scheduler.h"
#include "../sample/navigation_task.h"
#include "../sample/battery_level_check.h"
#include "../sample/screen_return_zero_check.h"
#include "../sample/screen_return_zero_task.h"
#include "../sample/docking_task.h"
#include "scheduler/scheduler_factory.h"

TEST(test_sequence_fallback_demo, test_sequence_fallback)
{
    auto battery_level_check = task::TaskFactory<BatteryLevelCheck>::createTask("battery_level_check");
    auto screen_return_zero_task = task::TaskFactory<ScreenReturnZeroTask>::createTask("screen_return_zero_task");
    auto screen_return_zero_check = task::TaskFactory<ScreenReturnZeroCheck>::createTask("screen_return_zero_check");
    auto navigation_task = task::TaskFactory<NavigationTask>::createTask("navigation_task");
    auto docking_task = task::TaskFactory<DockingTask>::createTask("docking_task");

    auto screen_return_scheduler = scheduler::SchedulerFactory<scheduler::FallbackScheduler>::createScheduler("screen_return_scheduler");
    screen_return_scheduler->appendTask(screen_return_zero_check);
    screen_return_scheduler->appendTask(screen_return_zero_task);

    auto recharge_scheduler = scheduler::SchedulerFactory<scheduler::SequenceScheduler>::createScheduler("recharge_scheduler");
    recharge_scheduler->appendScheduler(screen_return_scheduler);
    recharge_scheduler->appendTask(navigation_task);
    recharge_scheduler->appendTask(docking_task);

    auto time_recharge_scheduler = scheduler::SchedulerFactory<scheduler::FallbackScheduler>::createScheduler("time_recharge_scheduler");
    time_recharge_scheduler->appendTask(battery_level_check);
    time_recharge_scheduler->appendScheduler(recharge_scheduler);

    time_recharge_scheduler->run();
}

TEST(test_sequence_fallback_demo2, test_sequence_fallback)
{
    auto battery_level_check = task::TaskFactory<BatteryLevelCheck>::createTask("battery_level_check");
    auto screen_return_zero_task = task::TaskFactory<ScreenReturnZeroTask>::createTask("screen_return_zero_task");
    auto screen_return_zero_check = task::TaskFactory<ScreenReturnZeroCheck>::createTask("screen_return_zero_check");
    auto navigation_task = task::TaskFactory<NavigationTask>::createTask("navigation_task");

    auto screen_return_scheduler = scheduler::SchedulerFactory<scheduler::FallbackScheduler>::createScheduler("screen_return_scheduler");
    {
        screen_return_scheduler->appendTask(screen_return_zero_check);
        screen_return_scheduler->appendTask(screen_return_zero_task);
    }

    auto time_recharge_scheduler = scheduler::SchedulerFactory<scheduler::SequenceScheduler>::createScheduler("time_recharge_scheduler");
    time_recharge_scheduler->appendScheduler(screen_return_scheduler);
    time_recharge_scheduler->appendTask(battery_level_check);
    time_recharge_scheduler->appendTask(navigation_task);

    time_recharge_scheduler->run();

    EASE_INFO("done");
}

TEST(test_sequence_fallback_demo_pause, test_sequence_fallback)
{
    auto battery_level_check = task::TaskFactory<BatteryLevelCheck>::createTask("battery_level_check");
    auto screen_return_zero_task = task::TaskFactory<ScreenReturnZeroTask>::createTask("screen_return_zero_task");
    auto screen_return_zero_check = task::TaskFactory<ScreenReturnZeroCheck>::createTask("screen_return_zero_check");
    auto navigation_task = task::TaskFactory<NavigationTask>::createTask("navigation_task");
    auto docking_task = task::TaskFactory<DockingTask>::createTask("docking_task");

    auto screen_return_scheduler = scheduler::SchedulerFactory<scheduler::FallbackScheduler>::createScheduler("screen_return_scheduler");
    screen_return_scheduler->appendTask(screen_return_zero_check);
    screen_return_scheduler->appendTask(screen_return_zero_task);

    auto recharge_scheduler = scheduler::SchedulerFactory<scheduler::SequenceScheduler>::createScheduler("recharge_scheduler");
    recharge_scheduler->appendScheduler(screen_return_scheduler);
    recharge_scheduler->appendTask(navigation_task);
    recharge_scheduler->appendTask(docking_task);

    auto time_recharge_scheduler = scheduler::SchedulerFactory<scheduler::FallbackScheduler>::createScheduler("time_recharge_scheduler");
    time_recharge_scheduler->appendTask(battery_level_check);
    time_recharge_scheduler->appendScheduler(recharge_scheduler);

    std::thread([&time_recharge_scheduler]
                {
                    sleep(2);
                    time_recharge_scheduler->pause();
                    EASE_INFO("pause...");
                    sleep(10);
                    time_recharge_scheduler->resume();
                    EASE_INFO("resume...");
                }).detach();

    time_recharge_scheduler->run();
}
